﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;

namespace IntellectShop.Common
{
	public partial class Order
	{
		public static Common.Order RetrieveLast(string createdBy)
		{
			using (DB.IntellectShopDataContext dataContext = new DB.IntellectShopDataContext(Common.Globals.ConnectionString))
			{
				var query = (
							from order in dataContext.Orders
							where order.CreatedBy == createdBy
							orderby order.Created descending
							select order
							).Take(1).SingleOrDefault();

				if (query == null)
					return null;

				List<Common.OrderItem> items = new List<OrderItem>();
				foreach (DB.OrderItem itemDB in query.OrderItems)
				{
					items.Add(new Common.OrderItem
					{
						OrderItemID = itemDB.OrderItemID,
						OrderID = itemDB.OrderID,
						CommodityID = itemDB.CommodityID,
						Quantity = itemDB.Quantity,
						UnitPrice = new Common.Money { Amount = itemDB.UnitPrice, Currency = Currency.RUB },
						Created = itemDB.Created,
						CreatedBy = itemDB.CreatedBy
					});
				}

				Common.Order selectedOrder = new Common.Order
				{
					OrderID = query.OrderID,
					OrderOwnerID = query.OrderOwnerID,
					OrderItems = items,
					FirstName = query.FirstName,
					LastName = query.LastName,
					Address = query.Address,
					Country = query.Country,
					Email = query.Email,
					Phone = query.Phone,
					Notes = query.Notes,
					Created = query.Created,
					CreatedBy = query.CreatedBy,
					Updated = query.Updated,
					UpdatedBy = query.UpdatedBy
				};

				return selectedOrder;
			}
		}

		public static Common.Order RetrieveByID(int orderID, string createdBy)
		{
			using (DB.IntellectShopDataContext dataContext = new DB.IntellectShopDataContext(Common.Globals.ConnectionString))
			{
				var query = (
							from order in dataContext.Orders
							where order.OrderID == orderID &&
								(order.CreatedBy == createdBy || createdBy == null)
							select order
							).SingleOrDefault();

				if (query == null)
					return null;

				List<Common.OrderItem> items = new List<OrderItem>();
				foreach (DB.OrderItem itemDB in query.OrderItems)
				{
					items.Add(new Common.OrderItem
					{
						OrderItemID = itemDB.OrderItemID,
						OrderID = itemDB.OrderID,
						CommodityID = itemDB.CommodityID,
						Quantity = itemDB.Quantity,
						UnitPrice = new Common.Money { Amount = itemDB.UnitPrice, Currency = Currency.RUB },
						Created = itemDB.Created,
						CreatedBy = itemDB.CreatedBy
					});
				}

				Common.Order selectedOrder = new Common.Order
				{
					OrderID = query.OrderID,
					OrderOwnerID = query.OrderOwnerID,
					OrderItems = items,
					FirstName = query.FirstName,
					LastName = query.LastName,
					Address = query.Address,
					Country = query.Country,
					Email = query.Email,
					Phone = query.Phone,
					Notes = query.Notes,
					Created = query.Created,
					CreatedBy = query.CreatedBy,
					Updated = query.Updated,
					UpdatedBy = query.UpdatedBy
				};

				return selectedOrder;
			}
		}

		public static List<Common.Order> RetrieveAll()
		{
			using (DB.IntellectShopDataContext dataContext = new DB.IntellectShopDataContext(Common.Globals.ConnectionString))
			{
				var query =
							from order in dataContext.Orders
							orderby order.Created descending, order.OrderID descending
							select order;

				if (query == null)
					return null;

				List<Common.Order> orders = new List<Order>();
				foreach (DB.Order orderDB in query)
				{

					List<Common.OrderItem> items = new List<OrderItem>();
					foreach (DB.OrderItem itemDB in orderDB.OrderItems)
					{
						items.Add(new Common.OrderItem
						{
							OrderItemID = itemDB.OrderItemID,
							OrderID = itemDB.OrderID,
							CommodityID = itemDB.CommodityID,
							Quantity = itemDB.Quantity,
							UnitPrice = new Common.Money { Amount = itemDB.UnitPrice, Currency = Currency.RUB },
							Created = itemDB.Created,
							CreatedBy = itemDB.CreatedBy
						});
					}

					orders.Add(new Common.Order
					{
						OrderID = orderDB.OrderID,
						OrderOwnerID = orderDB.OrderOwnerID,
						OrderItems = items,
						FirstName = orderDB.FirstName,
						LastName = orderDB.LastName,
						Address = orderDB.Address,
						Country = orderDB.Country,
						Email = orderDB.Email,
						Phone = orderDB.Phone,
						Notes = orderDB.Notes,
						Created = orderDB.Created,
						CreatedBy = orderDB.CreatedBy,
						Updated = orderDB.Updated,
						UpdatedBy = orderDB.UpdatedBy
					});
				}

				return orders;
			}
		}

		public void Create(Cart cart, string createdBy)
		{
			if (cart == null)
				return;

			var cartItems = cart.GetCartItems();

			using (TransactionScope trans = new TransactionScope())
			{
				using (DB.IntellectShopDataContext dataContext = new DB.IntellectShopDataContext(Common.Globals.ConnectionString))
				{
					var orderDB = new DB.Order
					{
						OrderOwnerID = this.OrderOwnerID,
						FirstName = this.FirstName,
						LastName = this.LastName,
						Address = this.Address,
						Country = this.Country,
						Email = this.Email,
						Phone = this.Phone,
						Notes = this.Notes,
						Created = DateTime.Now,
						CreatedBy = createdBy
					};

					dataContext.Orders.InsertOnSubmit(orderDB);
					dataContext.SubmitChanges();

					foreach (var cartItem in cartItems)
					{
						var orderItem = new DB.OrderItem
						{
							OrderID = orderDB.OrderID,
							CommodityID = cartItem.Commodity.CommodityID,
							Quantity = cartItem.Count,
							UnitPrice = cartItem.Commodity.Price.Amount,
							Created = DateTime.Now,
							CreatedBy = createdBy
						};

						dataContext.OrderItems.InsertOnSubmit(orderItem);
					}

					dataContext.SubmitChanges();

					cart.EmptyCart(dataContext);
					this.OrderID = orderDB.OrderID;

					trans.Complete();
				}
			}
		}

		public void Update(string updatedBy)
		{
			using (TransactionScope trans = new TransactionScope())
			{
				using (DB.IntellectShopDataContext dataContext = new DB.IntellectShopDataContext(Common.Globals.ConnectionString))
				{
					var orderDB =
						(from order in dataContext.Orders
						 where order.OrderID == this.OrderID
						 select order).SingleOrDefault();

					orderDB.OrderOwnerID = this.OrderOwnerID;
					orderDB.FirstName = this.FirstName;
					orderDB.LastName = this.LastName;
					orderDB.Address = this.Address;
					orderDB.Country = this.Country;
					orderDB.Email = this.Email;
					orderDB.Phone = this.Phone;
					orderDB.Notes = this.Notes;
					orderDB.UpdatedBy = updatedBy;
					orderDB.Updated = DateTime.Now;

					dataContext.SubmitChanges();

					List<int> orderItemIDlist = new List<int>();
					this.OrderItems.ForEach(x => orderItemIDlist.Add(x.OrderItemID));

					var orderItemsForDelete =
							from orderItems in dataContext.OrderItems
							where !orderItemIDlist.Contains(orderItems.OrderItemID)
							select orderItems;
					dataContext.OrderItems.DeleteAllOnSubmit(orderItemsForDelete);
					dataContext.SubmitChanges();

					foreach (var orderItem in this.OrderItems)
					{
						var queryItem = (
							from item in dataContext.OrderItems
							where item.OrderItemID == orderItem.OrderItemID
							select item).SingleOrDefault();

						if (queryItem == null)
						{
							dataContext.OrderItems.InsertOnSubmit(new DB.OrderItem
							{
								OrderID = orderItem.OrderID,
								CommodityID = orderItem.CommodityID,
								Quantity = orderItem.Quantity,
								UnitPrice = orderItem.UnitPrice.Amount,
								Created = DateTime.Now,
								CreatedBy = updatedBy
							});
						}
						else
						{
							queryItem.OrderID = orderItem.OrderID;
							queryItem.OrderItemID = orderItem.OrderItemID;
							queryItem.CommodityID = orderItem.CommodityID;
							queryItem.Quantity = orderItem.Quantity;
							queryItem.UnitPrice = orderItem.UnitPrice.Amount;
							queryItem.Created = orderItem.Created;
							orderItem.CreatedBy = orderItem.CreatedBy;
						}

						dataContext.SubmitChanges();
					}

					trans.Complete();
				}
			}
		}

		public static void Delete(int orderID)
		{
			using (TransactionScope trans = new TransactionScope())
			{
				using (DB.IntellectShopDataContext dataContext = new DB.IntellectShopDataContext(Common.Globals.ConnectionString))
				{
					var orderDB = (from order in dataContext.Orders where order.OrderID == orderID select order).SingleOrDefault();

					var orderItemsDB = from item in dataContext.OrderItems where item.OrderID == orderID select item;
					dataContext.OrderItems.DeleteAllOnSubmit(orderItemsDB);
					dataContext.SubmitChanges();

					dataContext.Orders.DeleteOnSubmit(orderDB);
					dataContext.SubmitChanges();

					trans.Complete();
				}
			}
		}
	}
}
